package com.chatplus.application.aiprocessor.channel.img.chatgpt;

import com.chatplus.application.aiprocessor.channel.img.ImgAiProcessorService;
import com.chatplus.application.aiprocessor.provider.ImgAiProcessorServiceProvider;
import com.chatplus.application.common.exception.BadRequestException;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.domain.dto.extend.ImgResultDto;
import com.chatplus.application.enumeration.ImgAiPlatformEnum;
import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.entity.images.Image;
import com.unfbx.chatgpt.entity.images.ImageResponse;
import com.unfbx.chatgpt.entity.images.Item;
import com.unfbx.chatgpt.entity.images.SizeEnum;
import com.unfbx.chatgpt.function.KeyRandomStrategy;
import com.unfbx.chatgpt.interceptor.OpenAILogger;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ChatGPT 机器人画图处理器
 **/
@Service(value = ImgAiProcessorServiceProvider.SERVICE_NAME_PRE + "OPENAI")
public class ChatGPTImageProcessor extends ImgAiProcessorService {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(ChatGPTImageProcessor.class);

    public ImgResultDto process(String prompt) {
        initConfig();
        if (StringUtils.isNotEmpty(getErrMsg())) {
            throw new BadRequestException(getErrMsg());
        }
        try {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
            //!!!!!!测试或者发布到服务器千万不要配置Level == BODY!!!!
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(httpLoggingInterceptor)
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(600, TimeUnit.SECONDS)
                    .readTimeout(600, TimeUnit.SECONDS).build();
            OpenAiClient openAiClient = OpenAiClient.builder()
                    .apiHost(handleHost(getApiUrl()))
                    .apiKey(getApiKeyList())
                    //自定义key使用策略 默认随机策略
                    .keyStrategy(new KeyRandomStrategy())
                    .okHttpClient(okHttpClient)
                    .build();
            Image image = Image.builder()
                    .responseFormat(com.unfbx.chatgpt.entity.images.ResponseFormat.URL.getName())
                    .model(Image.Model.DALL_E_3.getName())
                    .prompt(prompt) // 提示语
                    .n(1) // 图片数量
                    .quality(Image.Quality.STANDARD.getName())
                    .size(SizeEnum.size_1024.getName())
//                    .style(Image.Style.NATURAL.getName())
                    .responseFormat("b64_json")
                    .build();
            ImageResponse imageResponse = openAiClient.genImages(image);
            LOGGER.message("图片生成完成，上传中...").info();
            Item item = imageResponse.getData().getFirst();
            String openUrl = item.getUrl();
            String base64 = item.getB64Json();
            ImgResultDto imgResultDto = new ImgResultDto();
            imgResultDto.setUrl(saveToOss(openUrl, base64));
            imgResultDto.setRevisedPrompt(item.getRevisedPrompt());
            LOGGER.message("图片生成完成，上传完成...").context("imgResultDto", imgResultDto).info();
            return imgResultDto;
        } catch (Exception e) {
            LOGGER.message("图片生成失败").exception(e).error();
            throw new BadRequestException("图片生成失败");
        }
    }

    @Override
    public ImgAiPlatformEnum getChannel() {
        return ImgAiPlatformEnum.DALL_E_3;
    }

    private String handleHost(String url) {
        Pattern pattern = Pattern.compile("(https?://[^/]+/)");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
}
